//
//  MSRequest.m
//  OrderingMerchantsSide
//
//  Created by iOS on 2018/10/8.
//  Copyright © 2018年 mls. All rights reserved.
//

#import "MSRequest.h"

@implementation MSRequest

+ (instancetype)request {
    return [[self alloc] init];
}

- (instancetype)init {
    self = [super init];
    if (self) {
        self.sessionManager = [AFHTTPSessionManager manager];
        // 可以请求的类型(content-type)
        self.sessionManager.requestSerializer = [AFJSONRequestSerializer serializer];
        // 接收content-type
        self.sessionManager.responseSerializer = [AFHTTPResponseSerializer serializer];
        self.sessionManager.responseSerializer.acceptableContentTypes =  [NSSet setWithObjects:@"application/json", @"text/json", @"text/xml", @"text/javascript", @"text/plain", @"text/html",@"image/png", @"image/jpeg", nil];
//        [self.sessionManager.requestSerializer setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
        // 请求队列的最大并发数
        //        self.sessionManager.operationQueue.maxConcurrentOperationCount = 5;
        // 请求超时的时间
        self.sessionManager.requestSerializer.timeoutInterval = 15;
    }
    return self;
}
/** GET */
- (void)ms_GET:(NSString *)URLString
    parameters:(nullable id)parameters
       headers:(nullable NSDictionary <NSString *, NSString *> *)headers
      progress:(nullable void (^)(NSProgress * _Nonnull))downloadProgress
       success:(nullable void (^)(NSURLSessionDataTask * _Nonnull, id _Nullable))success
       failure:(nullable void (^)(NSURLSessionDataTask * _Nullable, NSError * _Nonnull))failure
{
    self.operationQueue = self.sessionManager.operationQueue;
    [self.sessionManager.requestSerializer setValue:AccountModel.account.token
                                 forHTTPHeaderField:@"token"];
    if (!ms_dictIsEmpty(headers))
    {
        for (NSString *key in headers.allKeys)
        {
            [self.sessionManager.requestSerializer setValue:[headers objectForKey:key]
                                         forHTTPHeaderField:key];
        }
    }
    MSLog(@"%@\n接口 ===== get请求", URLString);
    
    ms_dispatch_global_async_safe(^{
        
        [self.sessionManager GET:URLString
                      parameters:parameters
                         headers:headers
                        progress:downloadProgress
                         success:success
                         failure:failure];
    });
}
/** POST */
- (void)ms_POST:(NSString *)URLString
     parameters:(nullable id)parameters
        headers:(nullable NSDictionary <NSString *, NSString *> *)headers
       progress:(nullable void (^)(NSProgress *uploadProgress))uploadProgress
        success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success
        failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure
{
    self.operationQueue = self.sessionManager.operationQueue;
    [self.sessionManager.requestSerializer setValue:AccountModel.account.token
                                 forHTTPHeaderField:@"token"];
    if (!ms_dictIsEmpty(headers))
    {
        for (NSString *key in headers.allKeys)
        {
            [self.sessionManager.requestSerializer setValue:[headers objectForKey:key]
                                         forHTTPHeaderField:key];
        }
    }
    
    MSLog(@"%@\n接口入参 ===== %@", URLString, [parameters ms_JSONObject]);

    ms_dispatch_global_async_safe(^{
        
        [self.sessionManager POST:URLString
                       parameters:parameters
                          headers:headers
                         progress:uploadProgress
                          success:success
                          failure:failure];
    });
}


#pragma mark -
/** get 请求 response content type = “image/png” */
- (void)ms_getImageDataWithURLStr1:(nonnull NSString *)URLStr
                          response:(nonnull void(^)(NSData * _Nullable data, NSString * _Nonnull msg))response
{
    [self ms_GET:[API_BASE_URL_STRING stringByAppendingString:URLStr]
      parameters:nil
         headers:nil
        progress:nil
         success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        
        ms_dispatch_main_async_safe(^{
            
            MSLog(@"%@\n接口回参 ===== %@", URLStr, responseObject);
            response([responseObject mutableCopy], @"成功");
        });
    }
         failure:^(NSURLSessionDataTask * _Nullable task, NSError *error) {
        
        ms_dispatch_main_async_safe(^{
            
            MSLog(@"%@\n接口回参 ===== %@", URLStr, error);
            response(nil, ms_error_message(error.code));
        });
    }];
}
/** get 请求 */
- (void)ms_getWithURLStr1:(nonnull NSString *)URLStr
               parameters:(nullable NSDictionary *)parameters
                 response:(nonnull void(^)(NSString * _Nonnull code, NSString * _Nullable dataJSON, NSString * _Nonnull msg))response
{
    [self ms_GET:[API_BASE_URL_STRING stringByAppendingString:URLStr]
      parameters:parameters
         headers:nil
        progress:nil
         success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        
        MSLog(@"%@\n接口回参 ===== %@", URLStr, [responseObject ms_JSONString]);
        NSDictionary *infoDic = [responseObject ms_JSONObject];
        NSString *code = MS_TEXT_STRING(infoDic[@"code"]);
        NSString *msg = MS_TEXT_STRING(infoDic[@"message"]);
        id data = infoDic[@"data"];
        NSString *dataJSON;
        if (data && ![data isKindOfClass:[NSNull class]])
        {
            dataJSON = [data ms_JSONString];
        }
        
        ms_dispatch_main_async_safe(^{
            
            response(code, dataJSON, msg);
        });
    }
         failure:^(NSURLSessionDataTask * _Nullable task, NSError *error) {
        
        ms_dispatch_main_async_safe(^{
            
            MSLog(@"%@\n接口回参 ===== %@", URLStr, error);
            response(MS_TEXT_STRING(@(error.code)), nil, ms_error_message(error.code));
        });
    }];
}
/** post 请求(可传请求头部信息) */
- (void)ms_postWithURLStr1:(nonnull NSString *)URLStr
                parameters:(nullable NSDictionary *)parameters
                   headers:(nullable NSDictionary *)headers
                  response:(nonnull void(^)(NSString * _Nonnull code, NSString * _Nullable dataJSON, NSString * _Nonnull msg))response
{
    [self ms_POST:[API_BASE_URL_STRING stringByAppendingString:URLStr]
       parameters:parameters
          headers:headers
         progress:nil
          success:^(NSURLSessionDataTask *task, id  _Nullable responseObject) {
        
        MSLog(@"%@\n接口回参 ===== %@", URLStr, [responseObject ms_JSONString]);
        NSDictionary *infoDic = [responseObject ms_JSONObject];
        NSString *code = MS_TEXT_STRING(infoDic[@"code"]);
        NSString *msg = MS_TEXT_STRING(infoDic[@"message"]);
        id data = infoDic[@"data"];
        NSString *dataJSON;
        if (data && ![data isKindOfClass:[NSNull class]])
        {
            dataJSON = [data ms_JSONString];
        }
        
        ms_dispatch_main_async_safe(^{
            
            response(code, dataJSON, msg);
        });
    }
          failure:^(NSURLSessionDataTask * _Nullable task, NSError *error) {
        
        ms_dispatch_main_async_safe(^{
            
            MSLog(@"%@\n接口回参 ===== %@", URLStr, error);
            response(MS_TEXT_STRING(@(error.code)), nil, ms_error_message(error.code));
        });
    }];
}
/** post 请求 */
- (void)ms_postWithURLStr1:(nonnull NSString *)URLStr
                parameters:(nullable NSDictionary *)parameters
                  response:(nonnull void(^)(NSString * _Nonnull code, NSString * _Nullable dataJSON, NSString * _Nonnull msg))response
{
    return [self ms_postWithURLStr1:URLStr parameters:parameters headers:nil response:response];
}


#pragma mark - RACSignal
/** get 请求image，return RACSignal */
- (RACSignal *)ms_getImageDataWithURLStr:(nonnull NSString *)URLStr
{
    return [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
        
        [self ms_getImageDataWithURLStr1:URLStr
                                response:^(NSData * _Nullable data, NSString * _Nonnull msg) {
            
            
            ms_dispatch_main_async_safe(^{
                
                if (!ms_objectIsEmpty(data))
                {
                    [subscriber sendNext:data];
                    [subscriber sendCompleted];
                }
                else
                {
                    [subscriber sendNext:msg];
                    [subscriber sendCompleted];
                }
            });
        }];
        
        return [RACDisposable disposableWithBlock:^{
            
        }];
    }];
}
/** get 请求(可传请求头部信息) */
- (RACSignal *)ms_getWithURLStr:(nonnull NSString *)URLStr
                     parameters:(nullable NSDictionary *)parameters
                        headers:(nullable NSDictionary *)headers
{
    return [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
        
        [self ms_GET:[API_BASE_URL_STRING stringByAppendingString:URLStr]
          parameters:parameters
             headers:nil
            progress:nil
             success:^(NSURLSessionDataTask *task, id  _Nullable responseObject) {
            
            ms_dispatch_main_async_safe(^{
                
                MSLog(@"%@\n接口回参 ===== %@", URLStr, [responseObject ms_JSONString]);
                [subscriber sendNext:[responseObject ms_JSONObject]];
                [subscriber sendCompleted];
            });
        }
             failure:^(NSURLSessionDataTask * _Nullable task, NSError *error) {
            
            ms_dispatch_main_async_safe(^{
                
                MSLog(@"%@\n接口回参 ===== %@", URLStr, error);
                [subscriber sendNext:ms_error_message(error.code)];
                [subscriber sendCompleted];
            });
        }];
        
        return [RACDisposable disposableWithBlock:^{
            
        }];
    }];
}
/** get 请求 */
- (RACSignal *)ms_getWithURLStr:(nonnull NSString *)URLStr
                     parameters:(nullable NSDictionary *)parameters
{
    return [self ms_getWithURLStr:URLStr parameters:nil headers:nil];
}
/** post 请求(可传请求头部信息)，return RACSignal */
- (RACSignal *)ms_postWithURLStr:(nonnull NSString *)URLStr
                      parameters:(nullable NSDictionary *)parameters
                         headers:(nullable NSDictionary *)headers
{
    return [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
        
        [self ms_POST:[API_BASE_URL_STRING stringByAppendingString:URLStr]
           parameters:parameters
              headers:headers
             progress:^(NSProgress *uploadProgress) {
            
        }
              success:^(NSURLSessionDataTask *task, id  _Nullable responseObject) {
            
            ms_dispatch_main_async_safe(^{
                
                MSLog(@"%@\n接口回参 ===== %@", URLStr, [responseObject ms_JSONString]);
                [subscriber sendNext:[responseObject ms_JSONObject]];
                [subscriber sendCompleted];
            });
        }
              failure:^(NSURLSessionDataTask * _Nullable task, NSError *error) {
            
            ms_dispatch_main_async_safe(^{
                
                MSLog(@"%@\n接口回参 ===== %@", URLStr, error);
                [subscriber sendNext:ms_error_message(error.code)];
                [subscriber sendCompleted];
            });
        }];
        
        return [RACDisposable disposableWithBlock:^{
            
        }];
    }];
}
/** post 请求 return RACSignal*/
- (RACSignal *)ms_postWithURLStr:(NSString *)URLStr
                      parameters:(NSDictionary *)parameters
{
    return [self ms_postWithURLStr:URLStr parameters:parameters headers:nil];
}


#pragma mark - 上传文件
/** 上传文件 */
- (RACSignal *)ms_uploadFile:(NSData *)file
                        name:(NSString *)name
                    fileName:(NSString *)fileName
                      URLStr:(nonnull NSString *)URLString
                  parameters:(nullable NSDictionary *)parameters
                     headers:(nullable NSDictionary *)headers
{
    return [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
        
        [self.sessionManager.requestSerializer setValue:AccountModel.account.token
                                     forHTTPHeaderField:@"token"];
        
        ms_dispatch_global_async_safe(^{
            
            [self.sessionManager POST:[API_BASE_URL_STRING stringByAppendingString:URLString]
                           parameters:parameters
                              headers:headers
            constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
                
                [formData appendPartWithFileData:file
                                            name:name//服务器用来解析的字段
                                        fileName:fileName//文件名.png
                                        mimeType:@"image/png"];
            } progress:^(NSProgress * _Nonnull uploadProgress) {
                
                //上传进度
                // @property int64_t totalUnitCount;     需要下载文件的总大小
                // @property int64_t completedUnitCount; 当前已经下载的大小
                CGFloat percent = 1.0 * uploadProgress.completedUnitCount / uploadProgress.totalUnitCount;
                MSLog(@"%@  上传进度:%@", fileName, [NSNumberFormatter localizedStringFromNumber:@(percent) numberStyle:NSNumberFormatterPercentStyle]);
                        
                ms_dispatch_main_async_safe(^{
                    
                    [subscriber sendNext:@(percent)];
                });
            } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
                
                ms_dispatch_main_async_safe(^{
                    
                    MSLog(@"%@\n接口回参 ===== %@", URLString, [responseObject ms_JSONString]);
                    [subscriber sendNext:[responseObject ms_JSONObject]];
                    [subscriber sendCompleted];
                });
            } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
                
                ms_dispatch_main_async_safe(^{
                    
                    MSLog(@"%@\n接口回参 ===== %@", URLString, error);
                    [subscriber sendNext:ms_error_message(error.code)];
                    [subscriber sendCompleted];
                });
            }];
        });
        
        return [RACDisposable disposableWithBlock:^{
            
        }];
    }];
}

@end
